import bean.IterationPoint;
import bean.KnnNode;
import bean.MagneticKnnNode;
import bean.MagneticNode;
import utils.FileRecord;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class IterationTest {

    private static List<IterationPoint> iterationPoints;
    private static List<MagneticNode> nodeList;
    private static String path = System.getProperty("user.dir")+"\\src" +  "\\result\\";

    private static String filePath;
    private static int readNum;

    public static void main(String[] args) {
        iterationPoints = new ArrayList<>();
        nodeList = new ArrayList<>();
        Scanner in = new Scanner(System.in);
        List<String> fileList = FileRecord.getFiles(path);
        if (fileList.size() > 0) {
            int n = fileList.size();
            System.out.println("请选择读取的地图文件编号");
            for (int i = 0; i < n; i++) {
                System.out.println((i + 1) + ":" + fileList.get(i));
            }
            readNum = in.nextInt();
            filePath = path + fileList.get((readNum - 1));
            System.out.println("请输入三轴地磁数据");
            //输入获取到的三轴地磁数据，对当前数据进行Knn操作
            double tarX = in.nextDouble();
            double tarY = in.nextDouble();
            double tarZ = in.nextDouble();
            //实例化初始叶子节点
            IterationPoint point = new IterationPoint(new MagneticNode(tarX, tarY, tarZ));
            //将所有的地磁指纹点存储进一个list中
            nodeList = DistHandler.generateMap(filePath);
            //第一次执行Knn操作，生成根节点及其三个子节点， 1+3
            point = magneticKnn(point);
            System.out.println("第一次迭代");
            //第二次执行Knn操作，针对三个子节点生成对应的子节点，1+3+9
            for (int i = 0; i < point.getSonNodes().size(); i++) {
                IterationPoint ansPoint = magneticKnn(point.getSonNodes().get(i));
                point.getSonNodes().set(i, ansPoint);
            }
            System.out.println(point.toString());
            //第三次执行Knn操作，1+3+9+27（理论上）
            System.out.println("第二次迭代");
            for (int i = 0; i < point.getSonNodes().size(); i++) {
                IterationPoint ansPoint = point.getSonNodes().get(i);
                for (int j = 0; j < ansPoint.getSonNodes().size(); j++) {
                    IterationPoint iterationPoint = magneticKnn(ansPoint.getSonNodes().get(j));
                    ansPoint.getSonNodes().set(j, iterationPoint);
                }
            }
            for (int i = 0; i < point.getSonNodes().size(); i++) {
                System.out.println(point.getSonNodes().get(i).toString());
            }
        }
    }

    /**
     * 返回三个或者三个以下的节点列表集合
     * @param point 父节点
     * @return 节点列表集合
     */
    private static IterationPoint magneticKnn(IterationPoint point) {
        IterationPoint returnPoint = new IterationPoint();
        int n = nodeList.size();
        List<MagneticKnnNode> distList = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            double dataMagX = nodeList.get(i).getMagX();
            double dataMagY = nodeList.get(i).getMagY();
            double dataMagZ = nodeList.get(i).getMagZ();
            double dist = (point.getNode().getMagX() - dataMagX) * (point.getNode().getMagX() - dataMagX)
                    + (point.getNode().getMagY() - dataMagY) * (point.getNode().getMagY() - dataMagY)
                    + (point.getNode().getMagZ() - dataMagZ) * (point.getNode().getMagZ() - dataMagZ);
            //将欧氏距离以及点编号添加进List中
            distList.add(new MagneticKnnNode(i + 1, Math.sqrt(dist), nodeList.get(i)));
        }
        //对dist列表进行排序
        distList.sort(MagneticKnnNode::compareTo);
        //生成结果列表
        List<IterationPoint> resList = new ArrayList<>();
        if (n < 3) {
            for (int i = 0; i < n; i++) {
                IterationPoint resPoint = new IterationPoint();
                resPoint.setNode(distList.get(i).getNode());
                resList.add(resPoint);
            }
        } else {
            for (int i = 0; i < 3; i++) {
                IterationPoint resPoint = new IterationPoint();
                resPoint.setNode(distList.get(i).getNode());
                resList.add(resPoint);
            }
        }
        //从指纹地图中删除点
        for (int i = 0; i < resList.size(); i++) {
            nodeList.remove(resList.get(i).getNode());
        }
        returnPoint.setSonNodes(resList);
        returnPoint.setNode(point.getNode());
        return returnPoint;
    }
}
